﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Collections;
using ITAP.ShprossesBuilder.Modelling.Comparers;
using ITAP.Core.Modelling;

namespace ITAP.ShprossesBuilder.Modelling.Components.Actions
{
    public class ActionAlignComponentsPositionsRelativeToModel : IComponentAction
    {
        private ModelControl modelControl;
        private List<Type> typesOfComponents;
        private ComponentAlign align;
        private RectangleF boundingBox;
        private bool indent;
        public ActionAlignComponentsPositionsRelativeToModel(ModelControl modelControl, Type[] typesOfComponents, ComponentAlign align, RectangleF modelBoundingBox, bool indent)
        {
            this.modelControl = modelControl;
            this.typesOfComponents = new List<Type>(typesOfComponents);
            this.align = align;
            this.boundingBox = modelBoundingBox;
            this.indent = indent;
        }

        #region IComponentAction Members

        public bool Action(IComponent component)
        {
            if (!typesOfComponents.Contains(component.GetType()))
                return false;
            List<IComponent> componentsToAlign = new List<IComponent>();
            foreach (IComponent selectedComponent in modelControl.ModelContainer.SelectedComponentsStack)
            {
                if (typesOfComponents.Contains(selectedComponent.GetType()))
                    componentsToAlign.Add(selectedComponent);
            }

            double offset;
            double x;
            double y;
            switch (align)
            {
                case ComponentAlign.Horizontal:
                    //componentsToAlign.Sort(new ComponentXAxisComparer());
                    if(indent)
                        offset = boundingBox.Width / (componentsToAlign.Count + 1);
                    else
                        offset = boundingBox.Width / (componentsToAlign.Count - 1);
                    x = boundingBox.X;
                    y = component.Position.Y;
                    for (int i = 0; i < componentsToAlign.Count; i++)
                    {
                        if (!indent)
                        {                            
                            //componentsToAlign[i].MoveTo(new ModelPoint(x, y));
                            componentsToAlign[i].MoveTo(new ModelPoint(x, componentsToAlign[i].Position.Y));
                            x += offset;
                        }
                        else
                        {
                            x += offset;
                            //componentsToAlign[i].MoveTo(new ModelPoint(x, y));
                            componentsToAlign[i].MoveTo(new ModelPoint(x, componentsToAlign[i].Position.Y));
                        }
                    }
                    return true;
                case ComponentAlign.Vertical:
                   // componentsToAlign.Sort(new ComponentYAxisComparer());
                    if(indent)
                        offset = boundingBox.Height / (componentsToAlign.Count + 1);
                    else
                        offset = boundingBox.Height / (componentsToAlign.Count - 1);

                    x = component.Position.X;
                    y = boundingBox.Y;
                    for (int i = 0; i < componentsToAlign.Count; i++)
                    {
                        if (!indent)
                        {                            
                            //componentsToAlign[i].MoveTo(new ModelPoint(x, y));
                            componentsToAlign[i].MoveTo(new ModelPoint(componentsToAlign[i].Position.X, y));
                            y += offset;
                        }
                        else
                        {
                            y += offset;
                            //componentsToAlign[i].MoveTo(new ModelPoint(x, y));
                            componentsToAlign[i].MoveTo(new ModelPoint(componentsToAlign[i].Position.X, y));
                        }
                    }
                    return true;
                default:
                    throw new NotImplementedException();
            }
            return false;
        }

        #endregion
    }
}
